`include "ascon_define.v"

module `ASCON_HASH_AM
(
    input                                        ascon_hash_clk_i,
    input                                        ascon_hash_rst_n_i,

    input                                        ascon_hash_am_en_i,
    input                                        ascon_hash_am_vld_i,
    input                                        ascon_hash_am_mode_i,
    input                                        ascon_hash_am_first_i,
    input                                        ascon_hash_am_last_i,
    input                             [`M_W-1:0] ascon_hash_am_m_i,

    output                            [`S_W-1:0] ascon_hash_am_s_o,
    input                                        ascon_hash_am_vld_o
);
//外信号
wire                                             en_p;
wire                                             vld_i_p;
wire                                             mode_p;
wire                                             first_p;
wire                                             last_p;
wire                                  [`M_W-1:0] m_p;
wire                                  [`S_W-1:0] s_p;
reg                                   [`S_W-1:0] s_r;
wire                                             vld_o_p;
//接口信号
wire                                  [`S_W-1:0] init_s_w;
wire                                  [`S_W-1:0] ori_s_w;
wire                                  [`S_W-1:0] xor_s_w;
wire                                  [`S_W-1:0] s_o_w;

//连接接口信号
assign en_p                  = ascon_hash_am_en_i;
assign vld_i_p               = ascon_hash_am_vld_i;
assign mode_p                = ascon_hash_am_mode_i;
assign first_p               = ascon_hash_am_first_i;
assign last_p                = ascon_hash_am_last_i;
assign m_p                   = ascon_hash_am_m_i;

assign ascon_hash_am_s_o     = s_p;
assign ascon_hash_am_vld_o   = vld_o_p;

//接口信号 生成

assign init_s_w              = (mode_p == 1'b0) ? {64'h01470194fc6528a6,
                                                   64'h738ec38ac0adffa7,
                                                   64'h2ec8e3296c76384c,
                                                   64'hd6f6a54d7f52377d,
                                                   64'ha13c42a223be8d87} :
                                                  {64'hee9398aadb67f03d,
                                                   64'h8bb21831c60f1002,
                                                   64'hb48a92db98d5da62,
                                                   64'h43189921b8f8e3e8,
                                                   64'h348fa5c9d525e140};

assign ori_s_w               = (first_p == 1'b0) ? s_r : init_s_w;

assign xor_s_w               = ori_s_w ^ {m_p,256'd0};

assign s_p                   = (last_p == 1'b0) ? s_o_w : xor_s_w;

always @(posedge ascon_hash_clk_i or negedge ascon_hash_rst_n_i)
begin : S_R_PROG
  if (ascon_hash_rst_n_i == 1'b0)
    s_r                 <= `S_W'b0;
  else
    s_r                 <= s_p;
end

`P12_8
u_p12_8
(
    .clk_i                             (ascon_hash_clk_i                       ),
    .rst_n_i                           (ascon_hash_rst_n_i                     ),
    .p12_8_en_i                        (en_p                                   ),
    .p12_8_mode_i                      (mode_p                                 ),
    .p12_8_vld_i                       (vld_i_p                                ),
    .p12_8_s_i                         (xor_s_w                                ),
    .p12_8_s_o                         (s_o_w                                  ),
    .p12_8_vld_o                       (vld_o_p                                )
);
endmodule